package com.lhd.qd.module.system.dict.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.core.type.TypeReference;
import com.lhd.qd.common.consts.RedisConsts;
import com.lhd.qd.common.base.BaseServiceImpl;
import com.lhd.qd.common.consts.WsCodeEnum;
import com.lhd.qd.common.util.JacksonUtils;
import com.lhd.qd.common.util.RedisUtils;
import com.lhd.qd.module.system.dict.dao.DictMapper;
import com.lhd.qd.module.system.dict.model.converter.AbstractDictConverter;
import com.lhd.qd.module.system.dict.model.dataobj.DictDO;
import com.lhd.qd.module.system.dict.model.vo.DictCacheVO;
import com.lhd.qd.module.system.dict.service.DictCacheService;
import com.lhd.qd.websocket.WebSocket;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.*;

@Slf4j
@Service
public class DictCacheServiceImpl extends BaseServiceImpl<DictMapper, DictDO> implements DictCacheService {

    @Autowired
    private WebSocket webSocket;

    @Override
    public void cacheAllDict() {

        LambdaQueryWrapper<DictDO> queryWrapper = Wrappers.<DictDO>lambdaQuery()
                .orderByAsc(DictDO::getTypeCode)
                .orderByAsc(DictDO::getOrderNo)
                .orderByAsc(DictDO::getCode);
        List<DictDO> doList = list(queryWrapper);

        RedisUtils.delete(RedisConsts.KEY_DICT_INFO);

        for (DictDO dataObj : doList) {
            Object obj = RedisUtils.hashGet(RedisConsts.KEY_DICT_INFO, dataObj.getTypeCode());
            if (obj != null) {
                List<DictCacheVO> list = JacksonUtils.toObj(obj.toString(), new TypeReference<List<DictCacheVO>>(){});
                if (list == null) {
                    list = new ArrayList<>();
                }
                list.add(AbstractDictConverter.INSTANCE.do2CacheVO(dataObj));
                RedisUtils.hashPut(RedisConsts.KEY_DICT_INFO, dataObj.getTypeCode(), JacksonUtils.toStr(list));
            }
            else {
                RedisUtils.hashPut(RedisConsts.KEY_DICT_INFO,
                        dataObj.getTypeCode(),
                        JacksonUtils.toStr(Collections.singleton(AbstractDictConverter.INSTANCE.do2CacheVO(dataObj))));
            }
        }
    }

    @Override
    public Map<String, List<DictCacheVO>> getDictCacheByTypeCodeList(List<String> typeCodeList) {
        Map<String, List<DictCacheVO>> resultMap = new HashMap<>();
        for (String typeCode : typeCodeList) {
            Object obj = RedisUtils.hashGet(RedisConsts.KEY_DICT_INFO, typeCode);
            if (obj != null) {
                resultMap.put(typeCode, JacksonUtils.toObj(obj.toString(), new TypeReference<List<DictCacheVO>>(){}));
            }
        }
        return resultMap;
    }

    @Async
    @Override
    public void refreshCache(String typeCode) {

        LambdaQueryWrapper<DictDO> queryWrapper = Wrappers.<DictDO>lambdaQuery()
                .eq(DictDO::getTypeCode, typeCode)
                .orderByAsc(DictDO::getOrderNo)
                .orderByAsc(DictDO::getCode);
        List<DictDO> doList = list(queryWrapper);
        System.out.println(doList);

        if (doList == null || doList.size() == 0) {
            RedisUtils.hashDelete(RedisConsts.KEY_DICT_INFO, typeCode);
        }
        else {
            List<DictCacheVO> voList = AbstractDictConverter.INSTANCE.doList2CacheVOList(doList);
            RedisUtils.hashPut(RedisConsts.KEY_DICT_INFO, typeCode, JacksonUtils.toStr(voList));
        }

        webSocket.send(WsCodeEnum.REFRESH_DICT);
    }
}
